package com.ease.component.controls.simplewizard {
    import com.ease.util.Diagnostics;
    import com.ease.component.interfaces.IWizardNavigator;

    import flash.events.EventDispatcher;

    import mx.events.PropertyChangeEvent;

    public class DefaultWizardNavigator extends EventDispatcher implements IWizardNavigator {
        public function DefaultWizardNavigator() {
        }

        public static const DEFAULT_PATH_ID:String = "default";

        private var pathMap:Object = new Object();

        private var currentPathId:String = null;

        protected function setCurrentPathId(id:String):void {
            //the flag indicates pathid is resetted not first
            //time initilization
            var isReset:Boolean = false;
            if (id != this.currentPathId) {
                var oldVal:String = this.currentPathId;
                if (id != null) {
                    isReset = true;
                }
            }
            this.currentPathId = id;

            if (isReset) {
                dispatchEvent(new PropertyChangeEvent(DialogWizard.WIZARD_PATH_CHANGED, false, false, null, "currentPathId", oldVal, id, this));
            }
        }

        /**
         * Add a collection of steps for the specified path id, and then these steps can
         * be touched by the path id. For a wizard, there can be more than one path, and
         * only one path (corresponding steps) are shown at one time.
         *
         * @param pathId A String for identifying a collection of WizardSteps.
         * @param steps Array of WizardStep
         */
        public function addPath(pathId:String, steps:Array):void {
            // make a copy of steps
            var newSteps:Array = new Array();
            for (var i:int = 0; i < steps.length; i++) {
                var step:WizardStep = steps[i];
                Diagnostics.assert(step.panelId != null, "The " + (i+1) + " panel misses panelId.")

                newSteps.push(step.clone());
            }

            pathMap[pathId] = newSteps;

            currentPathId = pathId;
        }

        /**
         * Check whether the panel (with panel id) is the first panel in current path.
         *
         * @param currentPanelId
         * @return
         */
        public function isFirst(currentPanelId:String):Boolean {
            var path:Array = pathMap[currentPathId];
            var index:int = indexOfStep(currentPanelId, path);

            if (index == 0) {
                return true;
            }
            return false;
        }

        /**
         * Check whether the panel (with panel id) is the last panel in current path.
         *
         * @param currentPanelId
         * @return
         *
         */
        public function isLast(currentPanelId:String):Boolean {
            var path:Array = pathMap[currentPathId];
            var index:int = indexOfStep(currentPanelId, path);

            if (index == path.length - 1) {
                return true;
            }
            return false;
        }

        /**
         * Find out the id of the next panel.
         *
         * @param currentPanelId
         * @return
         */
        public function getNextPanelId(currentPanelId:String):String {
            var path:Array = pathMap[currentPathId];
            var index:int = indexOfStep(currentPanelId, path);
            Diagnostics.assert(index >= 0 && index < path.length - 1,
               currentPanelId + " is the first step or does not exist.");

            var nextStep:WizardStep = path[index + 1] as WizardStep;
            return nextStep.panelId;
        }


        /**
         * Find out the id of the pervious panel.
         *
         * @param currentPanelId
         * @return
         */
        public function getPreviousPanelId(currentPanelId:String):String {
            var path:Array = pathMap[currentPathId];
            var index:int = indexOfStep(currentPanelId, path);
            Diagnostics.assert(index > 0,
               currentPanelId + " is the first step or does not exist.");

            var previousStep:WizardStep = path[index - 1] as WizardStep;
            return previousStep.panelId;
        }

        /**
         * Return the id of the first panel of the wizard.
         *
         * @return panelId
         */
        public function getVeryFirstPanelId():String {
            var path:Array = pathMap[currentPathId];
            return (path[0] as WizardStep).panelId;
        }

        /**
         * Get a collection of wizard step for the current path id.
         *
         * @return
         */
        public function getCurrentPath():Array {
            return pathMap[currentPathId];
        }

        // Get step index with step id.
        private function indexOfStep(panelId:String, path:Array):int {
           for (var i:int = 0; i < path.length; i++) {
              var step:WizardStep = path[i] as WizardStep;
              if (step.panelId == panelId) {
                 return i;
              }
           }

           return -1;
        }
    }
}
